﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Box2D.XNA;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

namespace Imagine
{
    class Squit : GameObject, IKeyboardListener, IContactListener   /*From Box2D*/
    {
        private int velMultiplier = 10; 
        private int impMultiplier = 200; 
        float xVelocity = 12.0f;
        float yVelocity = 12.0f;  
        Vector2 faceDir;  
        public enum eAnimation 
        {
            eIdle,
            eRunning,
            eJumping,
            eCelebrate            
        }

        enum eSquitState
        {
            eInAir,
            eOnGround
        }

        public  Squit(string texture)
        {
            //Register for Key Inputs
            InputManager.Instance().Register<IKeyboardListener>(this);
            TheWorld.Instance().PhysicsWorld.ContactListener = this;
            //Set Physics Properties
            m_squit = new PhysicsSprite(texture);
            m_squit.Density = 1.0f;
            m_squit.Friction = 1.0f;
            m_squit.Position = new Vector2(0,0);
            //m_squit.CollisionBody = new Microsoft.Xna.Framework.Vector2(13.0f,62);
            m_squit.BodyType = Box2D.XNA.BodyType.Dynamic;
            m_squit.FixedRotation = true;       //Will have to be true
            m_squit.Restitution = 0.0f;
            m_squit.InitPhysics(ShapeType.eSHAPE_CIRCLE);
            m_squit.Body.SetUserData("squit");          //Temporal Coherence here as i cannot do this before this statement
            m_squit.FrameCount = 11;
            //m_squit.AnimationType = AnimationType.eLoop;
            position = m_squit.Position;
            //Set Animation Properties            
           // m_squit.FrameSize = new Microsoft.Xna.Framework.Vector2(64.0f,64.0f);
            //m_squit.AddAnimation(new AnimInfo(22,1, AnimationType.eOnce) );      //Idle
            //m_squit.AddAnimation(new AnimInfo(23,10, AnimationType.eLoop) );     //Run
            //m_squit.AddAnimation(new AnimInfo(34,10,AnimationType.eOnce) );     //Jump
            //m_squit.AddAnimation(new AnimInfo(0,11,AnimationType.eOnce) );      //Celebrate
            faceDir = new Vector2(m_squit.Position.X , m_squit.Position.Y ) - InputManager.Instance().GetMousePos() ;
            //m_squit.Play(0);

            //Make default State as On_Ground
            m_currentState = eSquitState.eOnGround;
        }
        static public Vector2 position;

        void IncreaseVelocity(Vector2 vel)
        {
            Vector2 v = m_squit.Body.GetLinearVelocity();
            m_squit.Body.SetLinearVelocity(v + vel);
        }

        public void Move(Vector2 direction, float speed)
        {

        }

        public override bool Update(Microsoft.Xna.Framework.GameTime time)
        {
            Vector2 mousePos = InputManager.Instance().GetMousePos();
            Matrix mat = Engine.Instance().Camera.GetTransformation() ;
            
            //Vector2 pos = Vector2.Subtract(mousePos, (new Vector2( mat.Translation.X, mat.Translation.Y) ) );
            Vector2 pos = Vector2.Transform(mousePos ,Matrix.Invert( mat) );
           // Vector4 pos = Engine.Instance().Camera.GetTransformation() * new Vector4(mousePos,1.0f,1.0f)  ;
            faceDir = new Vector2(pos.X, pos.Y) - new Vector2(m_squit.Position.X, m_squit.Position.Y );
            Vector2 velocity = m_squit.Body.GetLinearVelocity();
            if(InputManager.Instance().IsKeyDown(Keys.A))
                velocity.X = -xVelocity; 
            if(InputManager.Instance().IsKeyDown(Keys.D))
                velocity.X = xVelocity;
            if(InputManager.Instance().IsKeyDown(Keys.W))
                velocity.Y = -yVelocity;
            if(InputManager.Instance().IsKeyDown(Keys.S))
                velocity.Y = yVelocity;

            m_squit.Body.SetLinearVelocity(velocity);
            position = m_squit.Position;
            return m_squit.Update(time);
        }

        public override bool Draw(Microsoft.Xna.Framework.GameTime time)
        {
            //Dont know wat Atan2 does, seriosuly, but gets my work done :) 
            m_squit.Angle = (float)Math.Atan2( faceDir.X, -faceDir.Y);
            return m_squit.Draw(time);
        }

        public void KeyUp(Keys[] upKeys)
        {
            if(m_currentState == eSquitState.eOnGround)
            {
                foreach(Keys key in upKeys)
                {
                   switch(key)
                   {
                       case Keys.W:
                       case Keys.A:
                       case Keys.S:
                       case Keys.D:
                           {
                                m_squit.Body.SetLinearVelocity(new Vector2(0.0f, 0.0f));
                                m_squit.Body.SetAngularVelocity(0.0f);
                                m_squit.Play((int)eAnimation.eIdle);
                                break;
                           }
                   }
                }
            }
            
        }

        public void KeyDown(Keys[] downKey)
        {
            
        }

        public void BeginContact(Contact contact) { }
        public void EndContact(Contact contact) 
        {
           
        }
        public void PreSolve(Contact contact, ref Manifold oldManifold) { }
        public void PostSolve(Contact contact, ref ContactImpulse impulse) 
        {
            Body bodyA = contact.GetFixtureA().GetBody();
            Body bodyB = contact.GetFixtureB().GetBody();

            //string str = (string)bodyA.GetUserData();

            //switch(str)
            //{
              //  case "ground":
                //    {
                  //      m_currentState = eSquitState.eOnGround;
                    //    break;
                    //}
            //}              
        }

        public PhysicsSprite   m_squit;
        #region Private_Parts
        
        eSquitState     m_currentState;
        #endregion
    }
}
